package com.xiaoq.sites.repository.impl;

import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.coms.util.MathUtil;
import com.xiaoq.sites.entity.SitesEntity;
import com.xiaoq.sites.entity.SitesPointEntity;
import com.xiaoq.sites.repository.ISitesRepository;
import com.xiaoq.tool.util.IdGeneratorUtil;
import com.xiaoq.vo.PagingVo;
import org.apache.commons.lang3.StringUtils;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
 * 
 * @author wang zhihao
 *
 */
@Repository
public class SitesRepositoryImpl implements ISitesRepository {
	@Autowired
	private Datastore datastore;
	
	private static final Logger LOG = LoggerFactory.getLogger(SitesRepositoryImpl.class);


	@Override
	public SitesEntity findById(String id) {
		if(StringUtils.isBlank(id)){
			return null;
		}
		Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class);
		sitesQuery.filter("_id", id).filter("delFlag", ConstantUtil.NOT_DELETE_STATUS);
		return sitesQuery.get();
	}

	@Override
	public boolean addSites(SitesEntity sitesEntity) {
		if(sitesEntity!=null){
			sitesEntity.setDelFlag(ConstantUtil.NOT_DELETE_STATUS);
			datastore.save(sitesEntity);
			return true;
		}
		
		return false;
	}

	@Override
	public boolean updateSites(SitesEntity sitesEntity) {
		
		if (sitesEntity != null) {
			String sitesId = sitesEntity.getId();
			Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class).field(IdGeneratorUtil.IDGENERATOR)
					.equal(sitesId);
			UpdateOperations<SitesEntity> sitesUpdate = datastore.createUpdateOperations(SitesEntity.class);
			if (sitesEntity.getCenterLongitude() != null){
				sitesUpdate = sitesUpdate.set("centerLongitude", sitesEntity.getCenterLongitude());
			}
			if (sitesEntity.getCenterLatitude() != null){
				sitesUpdate = sitesUpdate.set("centerLatitude", sitesEntity.getCenterLatitude());
			}
			if (sitesEntity.getMainEntryLongitude() != null){
				sitesUpdate = sitesUpdate.set("mainEntryLongitude", sitesEntity.getMainEntryLongitude());
			}
			if (sitesEntity.getMainEntryLatitude() != null){
				sitesUpdate = sitesUpdate.set("mainEntryLatitude", sitesEntity.getMainEntryLatitude());
			}
			if (sitesEntity.getAddress() != null){
				sitesUpdate = sitesUpdate.set("address", sitesEntity.getAddress());
			}
			if (sitesEntity.getName() != null){
				sitesUpdate = sitesUpdate.set("name", sitesEntity.getName());
			}
			if (sitesEntity.getShortName() != null){
				sitesUpdate = sitesUpdate.set("shortName", sitesEntity.getShortName());
			}
			if (sitesEntity.getLogo() != null){
				sitesUpdate = sitesUpdate.set("logo", sitesEntity.getLogo());
			}
			if (sitesEntity.getLevels() != null){
				sitesUpdate = sitesUpdate.set("levels", sitesEntity.getLevels());
			}
			if (sitesEntity.getZoneProvince() != null){
				sitesUpdate = sitesUpdate.set("zoneProvince", sitesEntity.getZoneProvince());
			}
			if (sitesEntity.getZoneCity() != null){
				sitesUpdate = sitesUpdate.set("zoneCity", sitesEntity.getZoneCity());
			}
			if (sitesEntity.getZoneDistrict() != null){
				sitesUpdate = sitesUpdate.set("zoneDistrict", sitesEntity.getZoneDistrict());
			}
			if (sitesEntity.getIntroduction() != null){
				sitesUpdate = sitesUpdate.set("introduction", sitesEntity.getIntroduction());
			}
			if (sitesEntity.getDetailInfo() != null){
				sitesUpdate = sitesUpdate.set("detailInfo", sitesEntity.getDetailInfo());
			}
			if (sitesEntity.getOpenSchedule() != null){
				sitesUpdate = sitesUpdate.set("openSchedule", sitesEntity.getOpenSchedule());
			}
			if (sitesEntity.getMainImgUrl() != null){
				sitesUpdate = sitesUpdate.set("mainImgUrl", sitesEntity.getMainImgUrl());
			}
			if (sitesEntity.getImgUrls() != null){
				sitesUpdate = sitesUpdate.set("imgUrls", sitesEntity.getImgUrls());
			}
			if (sitesEntity.getTags() != null){
				sitesUpdate = sitesUpdate.set("tags", sitesEntity.getTags());
			}
			if (sitesEntity.getMerchantId() != null){
				sitesUpdate = sitesUpdate.set("merchantId", sitesEntity.getMerchantId());
			}
			if (sitesEntity.getNotice() != null){
				sitesUpdate = sitesUpdate.set("notice", sitesEntity.getNotice());
			}
			if (sitesEntity.getEnterCert() != null){
				sitesUpdate = sitesUpdate.set("enterCert", sitesEntity.getEnterCert());
			}
			if (sitesEntity.getPrefPolicy() != null){
				sitesUpdate = sitesUpdate.set("prefPolicy", sitesEntity.getPrefPolicy());
			}
			if (sitesEntity.getTips() != null){
				sitesUpdate = sitesUpdate.set("tips", sitesEntity.getTips());
			}
			if (sitesEntity.getTraficTips() != null){
				sitesUpdate = sitesUpdate.set("traficTips", sitesEntity.getTraficTips());
			}
			if (sitesEntity.getPhoneNum() != null){
				sitesUpdate = sitesUpdate.set("phoneNum", sitesEntity.getPhoneNum());
			}
			if (sitesEntity.getAnnouncement() != null){
				sitesUpdate = sitesUpdate.set("announcement", sitesEntity.getAnnouncement());
			}
			if (sitesEntity.getAvgTime() != null){
				sitesUpdate = sitesUpdate.set("avgTime", sitesEntity.getAvgTime());
			}
			if (sitesEntity.getBestPeriod() != null){
				sitesUpdate = sitesUpdate.set("bestPeriod", sitesEntity.getBestPeriod());
			}
			if (sitesEntity.getStatus() != null){
				sitesUpdate = sitesUpdate.set("status", sitesEntity.getStatus());
			}

			if (sitesEntity.getMaxRadius() != null){
				sitesUpdate = sitesUpdate.set("maxRadius", sitesEntity.getMaxRadius());
			}
			if (sitesEntity.getCapacity() != null){
				sitesUpdate = sitesUpdate.set("capacity", sitesEntity.getMaxRadius());
			}
			if (sitesEntity.getZoneProvinceName() != null){
				sitesUpdate.set("zoneProvinceName", sitesEntity.getZoneProvinceName());
			}
			if (sitesEntity.getZoneCityName() != null){
				sitesUpdate.set("zoneCityName", sitesEntity.getZoneCityName());
			}
			if (sitesEntity.getZoneDistrictName() != null){
				sitesUpdate.set("zoneDistrictName", sitesEntity.getZoneDistrictName());
			}
			
			sitesUpdate = sitesUpdate.set("updatedAt", System.currentTimeMillis());
			datastore.update(sitesQuery, sitesUpdate);

			return true;
		}

		return false;
	}

	@Override
	public boolean delSites(String sitesId) {
		if(StringUtils.isNotBlank(sitesId)){
			Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class).field(IdGeneratorUtil.IDGENERATOR).equal(sitesId);
			UpdateOperations<SitesEntity> sitesUpdate = datastore.createUpdateOperations(SitesEntity.class).set("delFlag","1");
			datastore.update(sitesQuery, sitesUpdate);
			
			return true;
		}
		
		return false;
	}

	@Override
	public boolean delSites2(String sitesId) {
		Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class).field(IdGeneratorUtil.IDGENERATOR).equal(sitesId);
		datastore.delete(sitesQuery);
		return true;
	}

	@Override
	public List<SitesEntity> findSitesList(String zoneCity,String zoneDistrict) {
		List<SitesEntity> sitesEntityList = null;
		if(StringUtils.isNotBlank(zoneCity)) {
			Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class).field("zoneCity").equal(zoneCity);
			if(StringUtils.isNotBlank(zoneDistrict)){
				sitesQuery.field("zoneDistrict").equal(zoneDistrict);
			}
			long count = sitesQuery.count();
			if(count==0L){
				sitesQuery = datastore.createQuery(SitesEntity.class).field("zoneCity").equal(zoneCity);
			}
			sitesEntityList = sitesQuery.order("-updatedAt").asList();
		}

		Collections.sort(sitesEntityList, new Comparator<SitesEntity>() {

			@Override
			public int compare(SitesEntity sites1, SitesEntity sites2) {
				int status1 = sites1.getSort() - sites2.getSort();
				if (status1 == 0) {
					long status2 = sites1.getUpdatedAt() - sites2.getUpdatedAt();
					if (status2 < 0) {
						return 1;
					} else {
						return -1;
					}
				} else {
					if (status1 < 0) {
						return -1;
					} else {
						return 1;
					}
				}
			}
		});
		return sitesEntityList;
	}

	@Override
	public boolean updateSitesPayMethod(String sitesId, List<Integer> payMethodList) {
		if(StringUtils.isNotBlank(sitesId)){
			Query<SitesEntity> sitesEntityQuery = datastore.createQuery(SitesEntity.class).field(IdGeneratorUtil.IDGENERATOR)
					.equal(sitesId);
			SitesEntity sitesEntity = sitesEntityQuery.get();
			if(sitesEntity != null && StringUtils.isNotBlank(sitesEntity.getId())){
				UpdateOperations<SitesEntity> sitesUpdate = datastore.createUpdateOperations(SitesEntity.class);
				if(payMethodList != null){
					sitesUpdate.set("payMethodList", payMethodList);
					datastore.update(sitesEntityQuery, sitesUpdate);
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean updateSitesAuthenStatus(String merchantId, String authenStatus) {
		SitesEntity sites = datastore.find(SitesEntity.class).field("merchantId").equal(merchantId).get();
		if(sites!=null){
			sites.setAuthenStatus(authenStatus);
			datastore.save(sites);
			return true;
		}
		return false;
	}

	@Override
	public boolean updateAuthenStatus(String id, String authenStatus) {
		SitesEntity sites = datastore.get(SitesEntity.class,id);
		if(sites!=null){
			sites.setAuthenStatus(authenStatus);
			datastore.save(sites);
			return true;
		}else{
			LOG.error("查无此商店！！");
			return false;
		}
	}

	@Override
	public long count(String zoneCity, String zoneDistrict,String sitesStatus) {
		boolean isNotBlank = false;
		Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class);
		if(StringUtils.isNotBlank(zoneCity)){
			isNotBlank = true;
			sitesQuery.filter("zoneCity", zoneCity);
		}
		if(StringUtils.isNotBlank(zoneDistrict)){
			isNotBlank = true;
			sitesQuery.filter("zoneDistrict", zoneDistrict);
		}
		if(StringUtils.isNotBlank(sitesStatus)){
			isNotBlank = true;
			sitesQuery.filter("status", sitesStatus);
		}

		if(isNotBlank){
			return sitesQuery.count();
		}

		return 0L;
	}

	@Override
	public List<SitesEntity> getAllSites() {
		return datastore.createQuery(SitesEntity.class).asList();
	}

	@Override
	public List<SitesEntity> findByName(String name) {
		Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class);
		sitesQuery.field("name").equal(name);
		return sitesQuery.asList();
	}

	@Override
	public List<SitesEntity> getSitesByPoint(double latitude, double longitude, long nearM, PagingVo pagingVo) {
		double distance = nearM / MathUtil.METER_2_MONGO_DISTANCE;
		Query<SitesEntity> sitesQuery =  datastore.find(SitesEntity.class)
				.field("loc").near(longitude, latitude, distance);
		if (pagingVo != null){
			sitesQuery.offset(pagingVo.getPageOffset()).limit(pagingVo.getPs());
		}
		return sitesQuery.asList();
	}

	@Override
	public SitesEntity findSitesByMerchantId(String merchantId) {
		Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class);
		sitesQuery.field("merchantId").equal(merchantId);
		return sitesQuery.get();
	}

	@Override
	public List<SitesEntity> fuzzyBySitesName(String sitesName,String cityCode, PagingVo pagingVo) {
		Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class);
		sitesQuery.field("name").contains(sitesName);
		sitesQuery.field("zoneCity").equal(cityCode);
		if (pagingVo != null){
			sitesQuery.offset(pagingVo.getPageOffset()).limit(pagingVo.getPs());
		}
		return sitesQuery.asList();
	}

	@Override
	public List<SitesEntity> fuzzyBySitesAddr(String sitesAddr, PagingVo pagingVo) {
		Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class);
		sitesQuery.field("address").contains(sitesAddr);
		if (pagingVo != null){
			sitesQuery.offset(pagingVo.getPageOffset()).limit(pagingVo.getPs());
		}
		return sitesQuery.asList();
	}

	@Override
	public List<SitesEntity> findSitesList(String k, String cityCode, PagingVo pagingVo) {
		Query<SitesEntity> sitesQuery = datastore.createQuery(SitesEntity.class);
		sitesQuery.field("zoneCity").equal(cityCode);

		if(!org.springframework.util.StringUtils.isEmpty(k)){
			sitesQuery.field("name").contains(k);
		}
		if (pagingVo != null){
			sitesQuery.offset(pagingVo.getPageOffset()).limit(pagingVo.getPs());
		}
		return sitesQuery.asList();
	}
}
